import {
  polygon as turfpolygon,
  point as turfpoint,
  isobands as turfisobands,
  featureCollection as turffeatureCollection,
  bbox as turfbbox
} from "@turf/turf";
import Feature from "ol/Feature";
import WKT from "ol/format/WKT";
import {
  Point,
  LineString,
  MultiLineString,
  Polygon,
  MultiPolygon
} from "ol/geom";
import {
  Circle,
  RegularShape,
  Fill,
  Text,
  Stroke,
  Style,
  Icon
} from "ol/style";

import { levelData, wuzhouPolygon } from "../mapUtils/wuzhouBorder.js";
import olExtCrop from "ol-ext/filter/Crop";

var gridExtent = [];
var gridCellSize = 0;
var gridWidth = 0;
var gridHeight = 0;

function idwComputer(samplePoints, gridPoints, noData) {
  if (samplePoints.lenght < 3) return gridPoints;
  var m = samplePoints.length;
  var m1 = gridPoints.length;
  //过滤noData值
  var tempPoints = [];
  for (var i = 0; i < m; i++) {
    if (samplePoints[i][2] === noData) continue;
    tempPoints.push(samplePoints[i]);
  }
  samplePoints = tempPoints;
  var m0 = samplePoints.length;
  //距离列表
  var r = [];
  for (var i = 0; i < m1; i++) {
    for (var j = 0; j < m0; j++) {
      var tmpDis = Math.sqrt(
        Math.pow(gridPoints[i][0] - samplePoints[j][0], 2) +
          Math.pow(gridPoints[i][1] - samplePoints[j][1], 2)
      );
      r.push(tmpDis);
    }
  }
  //插值函数
  for (var i = 0; i < m1; i++) {
    //查找重复
    var ifFind = false;
    for (var j = m0 * i; j < m0 * i + m0; j++) {
      if (Math.abs(r[j]) < 0.0001) {
        gridPoints[i][2] = samplePoints[j - m0 * i][2];
        ifFind = true;
        break;
      }
    }
    if (ifFind) continue;
    var numerator = 0;
    var denominator = 0;

    for (var j = m0 * i; j < m0 * i + m0; j++) {
      numerator += samplePoints[j - m0 * i][2] / (r[j] * r[j]);
      denominator += 1 / (r[j] * r[j]);
    }
    gridPoints[i][2] = numerator / denominator;
  }
  return gridPoints;
}

function extentComputer(polygn) {
  var extent = turfbbox(polygn);
  var cellSize = cellSizeComputer(extent);
  var yNum = Math.ceil((extent[3] - extent[1]) / cellSize);
  var xNum = Math.ceil((extent[2] - extent[0]) / cellSize);

  gridExtent = extent;
  gridCellSize = cellSize;
  gridWidth = xNum + 3;
  gridHeight = yNum + 3;
  var grids = [];
  for (var i = yNum + 1; i > -2; i--) {
    for (var j = -1; j < xNum + 2; j++) {
      grids.push([extent[0] + cellSize * j, extent[1] + cellSize * i]);
    }
  }

  return grids;
}

function cellSizeComputer(extent) {
  var height = extent[3] - extent[1];
  var length = extent[2] - extent[0];
  var cellSize = 0.0001;
  if (length >= height) {
    cellSize = parseFloat((length / 100).toFixed(4));
  } else {
    cellSize = parseFloat((height / 100).toFixed(4));
  }
  if (cellSize < 0.0001) cellSize = 0.0001;
  return cellSize;
}

function isobandGrid(sampleData, noData, coordinates) {
  var polygon = turfpolygon(coordinates);
  var gridData = extentComputer(polygon);
  var idwedGrids = idwComputer(sampleData, gridData, noData);
  return {
    width: gridWidth,
    height: gridHeight,
    data: idwedGrids
  };
}

function isoBnad(sampleData) {
  let grids = isobandGrid(sampleData, 999999, [wuzhouPolygon]);
  let points = [];
  for (let i = 0; i < grids.data.length; i++) {
    points.push(
      turfpoint([grids.data[i][0], grids.data[i][1]], {
        z: grids.data[i][2]
      })
    );
  }
  let polygons = turfisobands(
    turffeatureCollection(points),
    [0, 2.5, 5, 10, 25, 50, 100, 10000],
    {
      zProperty: "z"
    }
  );
  let features = [];
  let format = new WKT();
  for (let i = 0; i < polygons.features.length; i++) {
    let coordinates = polygons.features[i]["geometry"]["coordinates"];
    let geometry = new MultiPolygon(coordinates);
    let feature = new Feature(
      format.readGeometry(
        format.writeGeometry(geometry, {
          dataProjection: "EPSG:3857",
          featureProjection: "EPSG:4326"
        })
      )
    );
    feature.setStyle(
      new Style({
        fill: new Fill({
          color: levelData[i]["color"]
        })
      })
    );
    features.push(feature);
  }
  return features;
}

function filterIsoband() {
  let format = new WKT();
  let feature = new Feature(
    format.readGeometry(
      format.writeGeometry(new Polygon([wuzhouPolygon]), {
        dataProjection: "EPSG:3857",
        featureProjection: "EPSG:4326"
      })
    )
  );
  let crop = new olExtCrop({
    feature: feature,
    inner: false
  });
  return crop;
}

export { isoBnad, filterIsoband };
